﻿using Basic.FormCollect;
using Basic.FormModel.QueryColumn;
using Basic.FormModel.QueryGroup;
using Basic.FormModel.QueryTable;
using Basic.FormRemoteModel.QueryTable.Model;
using Basic.FormService.Helper;
using Basic.FormService.Interface;
using WeDonekRpc.Helper;

namespace Basic.FormService.Extend
{
    internal class PhyQueryBodyService : IPhyQueryBodyService
    {
        private readonly IQueryTableCollect _Service;
        private readonly IQueryColumnCollect _Column;
        private readonly IQueryGroupCollect _Group;

        public PhyQueryBodyService ( IQueryTableCollect service,
            IQueryColumnCollect column,
            IQueryGroupCollect group )
        {
            this._Service = service;
            this._Column = column;
            this._Group = group;
        }

        public PhyQueryCol[] GetTableCols ( long tableId )
        {
            PhyQueryColDto[] cols = this._Column.GetsByTableId<PhyQueryColDto>(tableId, null);
            PhyQueryGroup[] groups = this._Group.GetsByTableId<PhyQueryGroup>(tableId);
            if ( cols.IsNull() && groups.IsNull() )
            {
                return null;
            }
            List<PhyQueryCol> list = new List<PhyQueryCol>();
            if ( !cols.IsNull() )
            {
                cols.ForEach(c =>
                {
                    if ( c.GroupId == 0 )
                    {
                        list.Add(new PhyQueryCol
                        {
                            Id = c.Id,
                            IsGroup = false,
                            IsHidden = c.IsHidden,
                            IsQueryHide = c.IsQueryHide,
                            IsNull = c.IsNull,
                            Sort = c.Sort,
                            Label = c.ColLabel,
                            FuncType = c.FuncType,
                            ShowMode = c.ShowMode,
                            Name = c.ColName,
                            DataType = c.GetDataType()
                        });
                    }
                });
            }

            if ( !groups.IsNull() )
            {
                groups.ForEach(c =>
                {
                    if ( c.ParentId == 0 )
                    {
                        list.Add(this._LoadChildren(c, groups, cols));
                    }
                });
            }

            return list.OrderBy(c => c.Sort).ToArray();
        }
        private PhyQueryCol _LoadChildren ( PhyQueryGroup group, PhyQueryGroup[] groups, PhyQueryColDto[] cols )
        {
            List<PhyQueryCol> list = new List<PhyQueryCol>();
            cols.ForEach(c =>
            {
                if ( c.GroupId == group.Id )
                {
                    list.Add(new PhyQueryCol
                    {
                        Id = c.Id,
                        IsGroup = false,
                        IsHidden = c.IsHidden,
                        IsNull = c.IsNull,
                        IsQueryHide = c.IsQueryHide,
                        Sort = c.Sort,
                        Label = c.ColLabel,
                        ShowMode = c.ShowMode,
                        FuncType = c.FuncType,
                        Name = c.ColName,
                        DataType = c.GetDataType()
                    });
                }
            });
            groups.ForEach(c =>
            {
                if ( c.ParentId == group.Id )
                {
                    list.Add(this._LoadChildren(c, groups, cols));
                }
            });
            return new PhyQueryCol
            {
                Id = group.Id,
                IsGroup = true,
                Label = group.GroupName,
                Sort = group.Sort,
                Children = list.OrderBy(a => a.Sort).ToArray()
            };
        }

        public PhyQueryTableBody[] GetBody ( long formId, bool isHidden )
        {
            PhyQueryTable[] tables = this._Service.Gets(formId);
            PhyQueryColumn[] cols = this._Column.GetsByFormId<PhyQueryColumn>(formId, true);
            if ( isHidden )
            {
                cols = cols.FindAll(a => a.IsHidden == false && a.IsQueryHide == false);
            }
            PhyQueryGroup[] groups = this._Group.GetsByFormId<PhyQueryGroup>(formId);
            return tables.ConvertAll(a =>
            {
                PhyQueryTableBody table = new PhyQueryTableBody
                {
                    Id = a.Id,
                    TableName = a.TableName,
                    Show = a.Show,
                    IsMainTable = a.IsMainTable,
                };
                PhyQueryColumn[] column = cols.FindAll(c => c.TableId == a.Id);
                PhyQueryGroup[] group = groups.FindAll(c => c.TableId == a.Id);
                List<PhyQueryColBody> list = new List<PhyQueryColBody>();
                if ( !group.IsNull() )
                {
                    group.ForEach(c =>
                    {
                        if ( c.ParentId == 0 )
                        {
                            PhyQueryColBody t = this._LoadChildren(c, groups, cols);
                            if ( t != null )
                            {
                                list.Add(t);
                            }
                        }
                    });
                }
                if ( !column.IsNull() )
                {
                    column.ForEach(c =>
                    {
                        if ( c.GroupId == 0 )
                        {
                            list.Add(new PhyQueryColBody
                            {
                                Label = c.ColLabel,
                                Id = c.Id,
                                Name = c.ColName,
                                Sort = c.Sort,
                                Width = c.Width,
                                IsHidden = c.IsHidden || c.IsQueryHide
                            });
                        }
                    });
                }
                table.Columns = list.OrderBy(a => a.Sort).ToArray();
                return table;
            });
        }
        private PhyQueryColBody _LoadChildren ( PhyQueryGroup group, PhyQueryGroup[] groups, PhyQueryColumn[] cols )
        {
            List<PhyQueryColBody> list = new List<PhyQueryColBody>();
            cols.ForEach(c =>
            {
                if ( c.GroupId == group.Id )
                {
                    list.Add(new PhyQueryColBody
                    {
                        Label = c.ColLabel,
                        Id = c.Id,
                        Name = c.ColName,
                        Sort = c.Sort,
                        Width = c.Width,
                        IsHidden = c.IsHidden || c.IsQueryHide
                    });
                }
            });
            groups.ForEach(c =>
            {
                if ( c.ParentId == group.Id )
                {
                    PhyQueryColBody t = this._LoadChildren(c, groups, cols);
                    if ( t != null )
                    {
                        list.Add(t);
                    }
                }
            });
            if ( list.Count > 0 )
            {
                return new PhyQueryColBody
                {
                    Id = group.Id,
                    IsGroup = true,
                    Label = group.GroupName,
                    Sort = group.Sort,
                    Children = list.OrderBy(a => a.Sort).ToArray()
                };
            }
            return null;
        }
    }
}
